
import store from '@/store'
import {
  intersection
} from 'lodash'
export function timeFix () {
  const time = new Date()
  const hour = time.getHours()
  return hour < 9
    ? '早上好'
    : hour <= 11
      ? '上午好'
      : hour <= 13
        ? '中午好'
        : hour < 20
          ? '下午好'
          : '晚上好'
}

export function welcome () {
  const arr = [
    '休息一会儿吧',
    '准备吃什么呢?',
    '要不要打一把 DOTA',
    '我猜你可能累了'
  ]
  let index = Math.floor(Math.random() * arr.length)
  return arr[index]
}

/**
 * 触发 window.resize
 */
export function triggerWindowResizeEvent () {
  let event = document.createEvent('HTMLEvents')
  event.initEvent('resize', true, true)
  event.eventType = 'message'
  window.dispatchEvent(event)
}

/**
 * 过滤对象中为空的属性
 * @param obj
 * @returns {*}
 */
export function filterObj (obj) {
  if (!(typeof obj === 'object')) {
    return
  }

  for (let key in obj) {
    if (
      obj.hasOwnProperty(key) &&
      (obj[key] == null || obj[key] === undefined || obj[key] === '')
    ) {
      delete obj[key]
    }
  }
  return obj
}

/**
 * 时间格式化
 * @param value
 * @param fmt
 * @returns {*}
 */
export function formatDate (value, fmt) {
  let regPos = /^\d+(\.\d+)?$/
  if (regPos.test(value)) {
    // 如果是数字
    let getDate = new Date(value)
    let o = {
      'M+': getDate.getMonth() + 1,
      'd+': getDate.getDate(),
      'h+': getDate.getHours(),
      'm+': getDate.getMinutes(),
      's+': getDate.getSeconds(),
      'q+': Math.floor((getDate.getMonth() + 3) / 3),
      S: getDate.getMilliseconds()
    }
    if (/(y+)/.test(fmt)) {
      fmt = fmt.replace(
        RegExp.$1,
        (getDate.getFullYear() + '').substr(4 - RegExp.$1.length)
      )
    }
    for (let k in o) {
      if (new RegExp('(' + k + ')').test(fmt)) {
        fmt = fmt.replace(
          RegExp.$1,
          RegExp.$1.length === 1
            ? o[k]
            : ('00' + o[k]).substr(('' + o[k]).length)
        )
      }
    }
    return fmt
  } else {
    // TODO
    value = value.trim()
    return value.substr(0, fmt.length)
  }
}

// 获取第一个menuItem当作redirect
function getRedirect (data) {
  let redirect = ''
  redirect = isRedirect(data)
  redirect = redirect.slice(0, redirect.length - 1)
  function isRedirect (data) {
    for (let i = 0; i < data.length; i++) {
      if (!data[i].hidden && data[i].path && data[i].status !== '0') { // 过滤隐藏项
        redirect += data[i].path + '/'
        if (data[i].children && data[i].children.length > 0) {
          redirect = isRedirect(data[i].children)
          return redirect
        } else {
          return redirect
        }
      }
    }
    return redirect
  }
  return redirect
}
// 生成首页路由
export function generateIndexRouter (d) {
  const data = JSON.parse(JSON.stringify(d))
  data.push({
    name: 'HomeDef',
    path: '/homeDef',
    redirect: getRedirect(data),
    hidden: true,
    components: {
      default: 'HomeDef'
    },
    meta: {
      title: '首页',
      icon: '#'
    }
  })
  let indexRouter = [{
    path: '/',
    name: 'dashboard',
    // component: () => import('@/components/layouts/BasicLayout'),
    component: resolve =>
      require(['@/components/layouts/TabLayout'], resolve),
    meta: {
      title: '路由'
    },
    // redirect: '/dashboard/analysis',
    redirect: getRedirect(data),
    children: [...generateChildRouters(data)]
  },
  {
    path: '*',
    redirect: '/404',
    hidden: true
  }
  ]
  return indexRouter
}

// 生成嵌套路由（子路由）

// function generateChildRouters(data) {
//   const routers = []
//   for (let item of data) {
//     if (item.component) {
//       let component = ''
//       if (item.component.indexOf('layouts') >= 0) {
//         component = 'components/' + item.component
//       } else {
//         component = 'views/' + item.component
//       }

//       // eslint-disable-next-line
//       let URL = (item.meta.url || '').replace(/{{([^}}]+)?}}/g, (s1, s2) =>
//         eval(s2)
//       ) // URL支持{{ window.xxx }}占位符变量
//       if (isURL(URL)) {
//         item.meta.url = URL
//       }
//       // online菜单路由加载逻辑
//       let componentPath = resolve => require(['@/' + component + '.vue'], resolve)
//       let menu = {
//         path: item.path.startsWith('/') ?
//           item.path.substr(1, item.path.length) : item.path,
//         name: item.name,
//         redirect: item.redirect,
//         component: componentPath,
//         hidden: item.hidden,
//         // component:()=> import(`@/views/${item.component}.vue`),
//         meta: {
//           module: item.name,
//           title: item.meta.title,
//           icon: item.meta.icon,
//           url: item.meta.url,
//           permissionList: item.meta.permissionList,
//           keepAlive: item.meta.keepAlive,
//           isBlank: item.meta.isBlank
//         }
//       }
//       /* if(item.alwaysShow){
//         menu.alwaysShow = true;
//         menu.redirect = menu.path;
//       } */
//       if (item.children && item.children.length > 0) {
//         menu.children = [...generateChildRouters(item.children)]
//       }
//       // 判断是否生成路由
//       if (item.route && item.route === '0') {
//         // //console.log(' 不生成路由 item.route：  '+item.route);
//         // //console.log(' 不生成路由 item.path：  '+item.path);
//       } else {
//         routers.push(menu)
//       }
//     }
//   }
//   return routers
// }
// 路径含layouts从components中获取组件，不含layouts从views中获取组件
const iframePath = 'components/layouts/IframePageView'
function hasLayouts (path, item) {
  let component = ''
  // 如果是菜单且是外链
  if (path.indexOf('layouts') >= 0) {
    component = 'components/' + path
  } else {
    if (item.type === '2' && item.meta.isLink === '1') {
      return iframePath
    }
    component = 'views/' + path
  }
  return component
}

// 如果是外链获取components中的URL
function getComponentsUrl (item) {
  if (item.type === '2' && item.meta.isLink === '1') {
    for (const key in item.components) {
      const path = item.components[key]
      if (path.indexOf('layouts') < 0) {
        return path
      }
    }
  }
  return ''
}

function generateChildRouters (data) {
  const routers = []
  for (let item of data) {
    if (item.components) {
      let componentKeyList = Object.keys(item.components)
      // eslint-disable-next-line
      // let URL = (item.meta.url || '').replace(/{{([^}}]+)?}}/g, (s1, s2) =>
      //   eval(s2)
      // ) // URL支持{{ window.xxx }}占位符变量
      // if (isURL(URL)) {
      //   item.meta.url = URL
      // }
      // online菜单路由加载逻辑
      let URL = getComponentsUrl(item)
      let componentPath = {}

      componentKeyList.forEach(el => {
        componentPath[el] = resolve => require(['@/' + hasLayouts(item.components[el], item) + '.vue'], resolve)
      })
      if (item.type === '3') continue// 如果是按钮类型，直接进行下一环节
      let menu = {
        path: item.path.startsWith('/')
          ? item.path.substr(1, item.path.length) : item.path,
        name: item.name,
        redirect: item.redirect,
        components: componentPath,
        hidden: item.hidden,
        // component:()=> import(`@/views/${item.component}.vue`),
        meta: {
          title: item.meta.title,
          icon: item.meta.icon,
          url: URL,
          permissionList: item.meta.permissionList,
          keepAlive: item.meta.keepAlive,
          isBlank: item.meta.isBlank,
          hidden: item.hidden,
          disabled: item.status === '0'
        }
      }
      /* if(item.alwaysShow){
        menu.alwaysShow = true;
        menu.redirect = menu.path;
      } */
      if (item.children && item.children.length > 0 && item.path) {
        menu.children = [...generateChildRouters(item.children)]
      }
      // 判断是否生成路由
      if (item.route && item.route === '0') {
        // //console.log(' 不生成路由 item.route：  '+item.route);
        // //console.log(' 不生成路由 item.path：  '+item.path);
      } else {
        routers.push(menu)
      }
    }
  }
  return routers
}

/**
 * 深度克隆对象、数组
 * @param obj 被克隆的对象
 * @return 克隆后的对象
 */
export function cloneObject (obj) {
  return JSON.parse(JSON.stringify(obj))
}

/**
 * 随机生成数字
 *
 * 示例：生成长度为 12 的随机数：randomNumber(12)
 * 示例：生成 3~23 之间的随机数：randomNumber(3, 23)
 *
 * @param1 最小值 | 长度
 * @param2 最大值
 * @return int 生成后的数字
 */
export function randomNumber () {
  // 生成 最小值 到 最大值 区间的随机数
  const random = (min, max) => {
    return Math.floor(Math.random() * (max - min + 1) + min)
  }
  if (arguments.length === 1) {
    let [length] = arguments
    // 生成指定长度的随机数字，首位一定不是 0
    let nums = [...Array(length).keys()].map(i =>
      i > 0 ? random(0, 9) : random(1, 9)
    )
    return parseInt(nums.join(''))
  } else if (arguments.length >= 2) {
    let [min, max] = arguments
    return random(min, max)
  } else {
    return Number.NaN
  }
}

/**
 * 随机生成字符串
 * @param length 字符串的长度
 * @param chats 可选字符串区间（只会生成传入的字符串中的字符）
 * @return string 生成的字符串
 */
export function randomString (length, chats) {
  if (!length) length = 1
  if (!chats) chats = '0123456789qwertyuioplkjhgfdsazxcvbnm'
  let str = ''
  for (let i = 0; i < length; i++) {
    let num = randomNumber(0, chats.length - 1)
    str += chats[num]
  }
  return str
}

/**
 * 随机生成uuid
 * @return string 生成的uuid
 */
export function randomUUID () {
  let chats = '0123456789abcdef'
  return randomString(32, chats)
}

/**
 * 下划线转驼峰
 * @param string
 * @returns {*}
 */
export function underLine2CamelCase (string) {
  return string.replace(/_([a-z])/g, function (all, letter) {
    return letter.toUpperCase()
  })
}

/**
 * 判断是否显示办理按钮
 * @param bpmStatus
 * @returns {*}
 */
export function showDealBtn (bpmStatus) {
  if (bpmStatus !== '1' && bpmStatus !== '3' && bpmStatus !== '4') {
    return true
  }
  return false
}

/**
 * 增强CSS，可以在页面上输出全局css
 * @param css 要增强的css
 * @param id style标签的id，可以用来清除旧样式
 */
export function cssExpand (css, id) {
  let style = document.createElement('style')
  style.type = 'text/css'
  style.innerHTML = `@charset "UTF-8"; ${css}`
  // 清除旧样式
  if (id) {
    let $style = document.getElementById(id)
    if ($style != null) $style.outerHTML = ''
    style.id = id
  }
  // 应用新样式
  document.head.appendChild(style)
}

/** 用于js增强事件，运行JS代码，可以传参 */
// options 所需参数：
//    参数名         类型            说明
//    vm             VueComponent    vue实例
//    event          Object          event对象
//    jsCode         String          待执行的js代码
//    errorMessage   String          执行出错后的提示（控制台）
export function jsExpand (options = {}) {
  // 绑定到window上的keyName
  let windowKeyName = 'Y_CLICK_EVENT_OPTIONS'
  if (typeof window[windowKeyName] !== 'object') {
    window[windowKeyName] = {}
  }

  // 随机生成JS增强的执行id，防止冲突
  let id = randomString(16, 'qwertyuioplkjhgfdsazxcvbnm'.toUpperCase())
  // 封装按钮点击事件
  let code = `
    (function (o_${id}) {
      try {
        (function (globalEvent, vm) {
          ${options.jsCode}
        })(o_${id}.event, o_${id}.vm)
      } catch (e) {
        o_${id}.error(e)
      }
      o_${id}.done()
    })(window['${windowKeyName}']['EVENT_${id}'])
  `
  // 创建script标签
  const script = document.createElement('script')
  // 将需要传递的参数挂载到window对象上
  window[windowKeyName]['EVENT_' + id] = {
    vm: options.vm,
    event: options.event,
    // 当执行完成时，无论如何都会调用的回调事件
    done () {
      // 执行完后删除新增的 script 标签不会撤销执行结果（已产生的结果不会被撤销）
      script.outerHTML = ''
      delete window[windowKeyName]['EVENT_' + id]
    },
    // 当js运行出错的时候调用的事件
    error (e) {
      console.group(
        `${options.errorMessage ||
        '用户自定义JS增强代码运行出错'}（${new Date()}）`
      )
      console.error(e)
      console.groupEnd()
    }
  }
  // 将事件挂载到document中
  script.innerHTML = code
  document.body.appendChild(script)
}

/**
 * 如果值不存在就 push 进数组，反之不处理
 * @param array 要操作的数据
 * @param value 要添加的值
 * @param key 可空，如果比较的是对象，可能存在地址不一样但值实际上是一样的情况，可以传此字段判断对象中唯一的字段，例如 id。不传则直接比较实际值
 * @returns {boolean} 成功 push 返回 true，不处理返回 false
 */
export function pushIfNotExist (array, value, key) {
  for (let item of array) {
    if (key && item[key] === value[key]) {
      return false
    } else if (item === value) {
      return false
    }
  }
  array.push(value)
  return true
}

/**
 * 可用于判断是否成功
 * @type {symbol}
 */
export const succeedSymbol = Symbol('success')
/**
 * 可用于判断是否失败
 * @type {symbol}
 */
export const failedSymbol = Symbol('fail')

/**
 * 使 promise 无论如何都会 resolve，除非传入的参数不是一个Promise对象或返回Promise对象的方法
 * 一般用在 Promise.all 中
 *
 * @param promise 可传Promise对象或返回Promise对象的方法
 * @returns {Promise<any>}
 */
export function alwaysResolve (promise) {
  return new Promise((resolve, reject) => {
    let p = promise
    if (typeof promise === 'function') {
      p = promise()
    }
    if (p instanceof Promise) {
      p.then(data => {
        resolve({
          type: succeedSymbol,
          data
        })
      }).catch(error => {
        resolve({
          type: failedSymbol,
          error
        })
      })
    } else {
      reject(
        new Error('alwaysResolve: 传入的参数不是一个Promise对象或返回Promise对象的方法')
      )
    }
  })
}

/**
 * 简单实现防抖方法
 *
 * 防抖(debounce)函数在第一次触发给定的函数时，不立即执行函数，而是给出一个期限值(delay)，比如100ms。
 * 如果100ms内再次执行函数，就重新开始计时，直到计时结束后再真正执行函数。
 * 这样做的好处是如果短时间内大量触发同一事件，只会执行一次函数。
 *
 * @param fn 要防抖的函数
 * @param delay 防抖的毫秒数
 * @returns {Function}
 */
export function simpleDebounce (fn, delay = 100) {
  let timer = null
  return function () {
    let args = arguments
    if (timer) {
      clearTimeout(timer)
    }
    timer = setTimeout(() => {
      fn.apply(null, args)
    }, delay)
  }
}

/**
 * 不用正则的方式替换所有值
 * @param text 被替换的字符串
 * @param checker  替换前的内容
 * @param replacer 替换后的内容
 * @returns {String} 替换后的字符串
 */
export function replaceAll (text, checker, replacer) {
  let lastText = text
  text = text.replace(checker, replacer)
  if (lastText !== text) {
    return replaceAll(text, checker, replacer)
  }
  return text
}

/** **金额大写转换*****/
export function changeMoneyToChinese (money) {
  var cnNums = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖'] // 汉字的数字
  var cnIntRadice = ['', '拾', '佰', '仟'] // 基本单位
  var cnIntUnits = ['', '万', '亿', '兆'] // 对应整数部分扩展单位
  var cnDecUnits = ['角', '分', '毫', '厘'] // 对应小数部分单位
  // var cnInteger = "整"; //整数金额时后面跟的字符
  var cnIntLast = '元' // 整型完以后的单位
  var maxNum = 999999999999999.9999 // 最大处理的数字

  var IntegerNum // 金额整数部分
  var DecimalNum // 金额小数部分
  var ChineseStr = '' // 输出的中文金额字符串
  var parts // 分离金额后用的数组，预定义
  if (money === '') {
    return ''
  }
  money = parseFloat(money)
  if (money >= maxNum) {
    window.alert('超出最大处理数字')
    return ''
  }
  if (money === 0) {
    // ChineseStr = cnNums[0]+cnIntLast+cnInteger;
    ChineseStr = cnNums[0] + cnIntLast
    // document.getElementById("show").value=ChineseStr;
    return ChineseStr
  }
  money = money.toString() // 转换为字符串
  if (money.indexOf('.') === -1) {
    IntegerNum = money
    DecimalNum = ''
  } else {
    parts = money.split('.')
    IntegerNum = parts[0]
    DecimalNum = parts[1].substr(0, 4)
  }
  if (parseInt(IntegerNum, 10) > 0) { // 获取整型部分转换
    let zeroCount = 0
    let IntLen = IntegerNum.length
    for (let i = 0; i < IntLen; i++) {
      let n = IntegerNum.substr(i, 1)
      let p = IntLen - i - 1
      let q = p / 4
      let m = p % 4
      if (n === '0') {
        zeroCount++
      } else {
        if (zeroCount > 0) {
          ChineseStr += cnNums[0]
        }
        zeroCount = 0 // 归零
        ChineseStr += cnNums[parseInt(n)] + cnIntRadice[m]
      }
      if (m === 0 && zeroCount < 4) {
        ChineseStr += cnIntUnits[q]
      }
    }
    ChineseStr += cnIntLast
    // 整型部分处理完毕
  }
  if (DecimalNum !== '') { // 小数部分
    let decLen = DecimalNum.length
    for (let i = 0; i < decLen; i++) {
      let n = DecimalNum.substr(i, 1)
      if (n !== '0') {
        ChineseStr += cnNums[Number(n)] + cnDecUnits[i]
      }
    }
  }
  if (ChineseStr === '') {
    // ChineseStr += cnNums[0]+cnIntLast+cnInteger;
    ChineseStr += cnNums[0] + cnIntLast
  }
  /* else if( DecimalNum == '' ){
        ChineseStr += cnInteger;
        ChineseStr += cnInteger;
    } */
  return ChineseStr
}

export function hasPermissions (permissions) { // 判断当前角色是否拥有特定角色权限
  const needPermissions = permissions || []
  let permissionList = store.getters && store.getters.permissionList
  let roleList = store.getters && store.getters.roleList
  if (permissionList.length === 0) return false

  if (permissionList.includes('*:*:*')) return true

  // 判断用户是否拥有可以访问的权限
  const mergePermissions = intersection(needPermissions, permissionList)
  const mergeRoles = intersection(needPermissions, roleList)

  // 如果没有，则验证不通过
  return !!mergePermissions.length || !!mergeRoles.length
}
